import { reportError } from '../utils/request';
import { config } from '../utils/config';

const xhrMonitor = () => {
  const { apiStatusIgnore } = config;
  const OldXHR = window.XMLHttpRequest;
  const _oldSend = OldXHR.prototype.send;
  const _handleEvent = (event) => {
    if (event && event.currentTarget && !apiStatusIgnore.includes(event.currentTarget.status)) {
      const { status, responseURL: url, statusText, response } = event.currentTarget;
      reportError({
        type: 'api',
        location: window?.location?.href || '',
        status,
        statusText,
        url,
        response,
      });
    }
  };
  OldXHR.prototype.send = function () {
    if (this.addEventListener) {
      this.addEventListener('error', _handleEvent);
      this.addEventListener('load', _handleEvent);
      this.addEventListener('abort', _handleEvent);
    } else {
      const _oldStateChange = this.onreadystatechange;
      this.onreadystatechange = function (event) {
        if (this.readyState === 4) {
          _handleEvent(event);
        }
        _oldStateChange && _oldStateChange.apply(this, arguments);
      };
    }
    return _oldSend.apply(this, arguments);
  };
  window.XMLHttpRequest = OldXHR;
};

const fetchMonitor = () => {
  const { apiStatusIgnore, server } = config;
  if (!window.fetch) return;
  const oldFetch = window.fetch;
  window.fetch = function () {
    return oldFetch.apply(this, arguments)
      .then(res => {
        const { status, statusText, url } = res;
        if (!apiStatusIgnore.includes(status)) {
          if (url === `${server}/error`) return; // 如果是错误上报接口就返回，防止无限循环
          reportError({
            type: 'api',
            location: window?.location?.href || '',
            status,
            statusText,
            url,
            response: res.json(), // 暂且放着
          });
        }
        return res;
      }); // 如果出现非接口错误，会被其他 monitor 捕获到
  };
};

const start = () => {
  xhrMonitor();
  fetchMonitor();
};

export default start;
